﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace Common.XmlConfig
{
    public class ConfigMgr
    {
        public string XmlConfigFile;
        private ConfigGroup _WebSiteConfig;
        private XmlDocument _Xml;

        /// <summary>
        /// 取得配置信息
        /// </summary>
        [Obsolete("请使用Settings或Groups")]
        public ConfigGroup WebSiteConfig
        {
            get
            {
                return _WebSiteConfig;
            }
        }
        /// <summary>
        /// 快速取得数值
        /// </summary>
        /// <param name="gkey">GroupKey</param>
        /// <param name="skey">SettingKey</param>
        /// <returns></returns>
        public string this[string gkey, string skey]
        {
            get
            {
                return Groups[gkey].Settings[skey].Value;
            }
        }
        /// <summary>
        /// 取得配置信息
        /// </summary>
        public ConfigList<ConfigSetting> Settings
        {
            get
            {
                return _WebSiteConfig.Settings;
            }
        }
        /// <summary>
        /// 配置信息分组
        /// </summary>
        public ConfigList<ConfigGroup> Groups
        {
            get
            {
                return _WebSiteConfig.Groups;
            }
        }
        /// <summary>
        /// Xml文档
        /// </summary>
        public XmlDocument XmlDoc
        {
            get
            {
                if (_Xml == null)
                {
                    _Xml = new XmlDocument();
                    _Xml.Load(XmlConfigFile);
                }
                return _Xml;
            }
        }
        /// <summary>
        /// 创建配置信息对象
        /// </summary>
        /// <param name="XmlFilePath"></param>
        public ConfigMgr(string xmlConfigFile)
        {
            this.XmlConfigFile = xmlConfigFile;
            LoadConfig();
        }

        #region 私有方法

        /// <summary>
        /// 加载配置
        /// </summary>
        private void LoadConfig()
        {
            var RootNode = XmlDoc.SelectSingleNode("WebSiteConfig");
            _WebSiteConfig = new ConfigGroup("WebSiteConfig", "配置文件目录");
            _WebSiteConfig.XmlPath = "/WebSiteConfig";
            ReadConfigGroup(_WebSiteConfig);
        }
        /// <summary>
        /// 循环读取配置文件
        /// </summary>
        /// <param name="ParentGroup"></param>
        private void ReadConfigGroup(ConfigGroup ParentGroup)
        {
            var BaseNode = XmlDoc.SelectSingleNode(ParentGroup.XmlPath);
            foreach (XmlNode node in BaseNode.ChildNodes)
            {
                try
                {
                    if (node.Name == "ConfigGroup")
                    {
                        ConfigGroup group = new ConfigGroup(node);
                        group.XmlPath = ParentGroup.XmlPath + "/ConfigGroup[@Key='" + group.Key + "']";
                        ParentGroup.AddGroup(group);

                        ///递归查找子元素
                        ReadConfigGroup(group);
                    }
                    if (node.Name == "Setting")
                    {
                        ConfigSetting setting = new ConfigSetting(node);
                        setting.XmlPath = ParentGroup.XmlPath + "/Setting[@Key='" + setting.Key + "']";
                        ParentGroup.AddSetting(setting);
                    }
                }
                catch (System.ArgumentException argexp)
                {
                    throw new ArgumentException(string.Format("节点：{0}，Type类型错误，{1}", node.OuterXml, argexp.Message));
                }
                catch (Exception exp)
                {
                    throw new Exception(string.Format("节点：{0}，{1}", node.OuterXml, exp.Message));
                }
            }
        }
        /// <summary>
        /// 修改配置信息
        /// </summary>
        /// <param name="setting"></param>
        private void UpdSetting(ConfigSetting setting)
        {
            XmlElement node = (XmlElement)XmlDoc.SelectSingleNode(setting.XmlPath);
            node.SetAttribute("Text", setting.Text);
            node.SetAttribute("Value", setting.Value);
            node.SetAttribute("Type", setting.Type.ToString());
        }
        /// <summary>
        /// 修改组名
        /// </summary>
        /// <param name="group"></param>
        private void UpdGroup(ConfigGroup group)
        {
            XmlElement groupnode = (XmlElement)XmlDoc.SelectSingleNode(group.XmlPath);
            groupnode.SetAttribute("Text", group.Text);
            foreach (var g in group.Groups)
            {
                UpdGroup(g);
            }
            foreach (var s in group.Settings)
            {
                UpdSetting(s);
            }
        }
        #endregion

        #region 操作
        /// <summary>
        /// 添加配置节点
        /// </summary>
        /// <param name="parentgroup"></param>
        /// <param name="newsetting"></param>
        public void AddSetting(ConfigGroup parentgroup, ConfigSetting newsetting)
        {
            var rootnode = XmlDoc.SelectSingleNode(parentgroup.XmlPath);
            XmlElement settingnode = XmlDoc.CreateElement("Setting");
            settingnode.SetAttribute("Key", newsetting.Key);
            settingnode.SetAttribute("Text", newsetting.Text);
            settingnode.SetAttribute("Value", newsetting.Value);
            settingnode.SetAttribute("Type", newsetting.Type.ToString());
            rootnode.AppendChild(settingnode);
            XmlDoc.Save(XmlConfigFile);
            //LoadConfig();
        }

        /// <summary>
        /// 添加分组
        /// </summary>
        /// <param name="parentgroup"></param>
        /// <param name="newgroup"></param>
        public void AddGroup(ConfigGroup parentgroup, ConfigGroup newgroup)
        {
            var rootnode = XmlDoc.SelectSingleNode(parentgroup.XmlPath);
            XmlElement groupnode = XmlDoc.CreateElement("ConfigGroup");
            groupnode.SetAttribute("Key", newgroup.Key);
            groupnode.SetAttribute("Text", newgroup.Text);
            rootnode.AppendChild(groupnode);
            XmlDoc.Save(XmlConfigFile);
            //LoadConfig();
        }

        /// <summary>
        /// 修改配置信息
        /// </summary>
        /// <param name="setting"></param>
        public void UpdateSetting(ConfigSetting setting)
        {
            UpdSetting(setting);
            XmlDoc.Save(XmlConfigFile);
        }

        /// <summary>
        /// 修改组名
        /// </summary>
        /// <param name="group"></param>
        public void UpdateGroup(ConfigGroup group)
        {
            UpdGroup(group);
            XmlDoc.Save(XmlConfigFile);
        }
        #endregion
    }
}
